#include "tcp_segment.h"
#include "extract.h"
#include <string.h>
#include "tcp_conversitons.h"

extern TCPConversiations g_tcpconvs;

TCPSegment::TCPSegment(const u_char *tcp_begin, u_int len, const u_char *ip, u_int fragmented)
    :tp((const struct tcphdr *)tcp_begin),ip((const struct ip *)ip), fragmented(fragmented),length(len)
{

}

int TCPSegment::dissection()
{
    u_int hlen;
    uint16_t sport;
    uint16_t dport;

    rev = 0;
    sport = EXTRACT_16BITS(&tp->th_sport);
    dport = EXTRACT_16BITS(&tp->th_dport);

    hlen = TH_OFF(tp) * 4;

    if (hlen < sizeof(*tp)) {
        printf(" tcp %d [bad hdr length %u - too short, < %lu]",
               length - hlen, hlen, (unsigned long)sizeof(*tp));
        return 0;
    }

    seq = EXTRACT_32BITS(&tp->th_seq);
    ack = EXTRACT_32BITS(&tp->th_ack);
    win = EXTRACT_16BITS(&tp->th_win);
    urp = EXTRACT_16BITS(&tp->th_urp);

    flags = tp->th_flags;

    if(flags & TH_ACK)
    {
        const struct in_addr *src;
        const struct in_addr *dst;

        src = &ip->ip_src;
        dst = &ip->ip_dst;
        if (sport > dport)
            rev = 1;
        else if (sport == dport) {
            if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                rev = 1;
        }
        if (rev) {
            memcpy(&tha.src, dst, sizeof ip->ip_dst);
            memcpy(&tha.dst, src, sizeof ip->ip_src);
            tha.port = dport << 16 | sport;
        } else {
            memcpy(&tha.dst, dst, sizeof ip->ip_dst);
            memcpy(&tha.src, src, sizeof ip->ip_src);
            tha.port = sport << 16 | dport;
        }
        if (hlen > length) {
            printf(" [bad hdr length %u - too long, > %u]",
                   hlen, length);
            return 0;
        }
        payloadlen = length-hlen;
        printf("payload %d = length %d - hlen %d\n", payloadlen, length, hlen);
        payload = new u_char[payloadlen];
        memcpy(payload, (char *)tp+hlen, payloadlen);
        g_tcpconvs.add(tha, this);

    }

    return 0;
}
